package vis.app.components;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

import vis.app.controller.AppController;
import vis.app.utils.Utils;
import vis.items.visualItem.EVisualType;

public class PanelSelectItem extends JPanel implements IPanelComponent {

	private static final long serialVersionUID = 84228683321203900L;

	DefaultMutableTreeNode nodeBasicDS;
	DefaultMutableTreeNode nodeAdvanceDS;
	DefaultMutableTreeNode nodeGraphDS;
	DefaultMutableTreeNode nodeSortingAlgo;
	DefaultMutableTreeNode nodeGraphAlgo;
	DefaultMutableTreeNode nodeMisc;

	@Override
	public void init() {
		DefaultMutableTreeNode root = createTreeNodes();
		final JTree tree = createTree(root);
		addNodeListener(tree);
	}

	private DefaultMutableTreeNode createTreeNodes() {
		DefaultMutableTreeNode root = new DefaultMutableTreeNode(
				"DATA_STRUCTURES_AND_ALGORITHMS");

		nodeBasicDS = new DefaultMutableTreeNode(
				EVisualType.BASIC_DATA_STRUCTURE);
		nodeAdvanceDS = new DefaultMutableTreeNode(
				EVisualType.ADV_DATA_STRUCTURE);
		nodeGraphDS = new DefaultMutableTreeNode(
				EVisualType.GRAPH_DATA_STRUCTURE);
		nodeSortingAlgo = new DefaultMutableTreeNode(
				EVisualType.SORTING_ALGO);
		nodeGraphAlgo = new DefaultMutableTreeNode(
				EVisualType.GRAPH_ALGO);
		nodeMisc = new DefaultMutableTreeNode(EVisualType.MISC);

		root.add(nodeBasicDS);
		root.add(nodeAdvanceDS);
		root.add(nodeGraphDS);
		root.add(nodeSortingAlgo);
		root.add(nodeGraphAlgo);
		root.add(nodeMisc);

		return root;
	}

	private JTree createTree(DefaultMutableTreeNode root) {
		JTree tree = new JTree(root);
		tree.setCellRenderer(new ItemTreeCellRenderer());

		final Font currentFont = tree.getFont();
		final Font bigFont = new Font(
				currentFont.getName(),
				currentFont.getStyle(),
				currentFont.getSize() + 5);
		tree.setFont(bigFont);
		// tree.putClientProperty("JTree.lineStyle", "Horizontal");

		JScrollPane pane = new JScrollPane(tree);
		pane.setPreferredSize(this.getPreferredSize());

		this.setLayout(new BorderLayout());
		this.add(pane, BorderLayout.CENTER);

		return tree;
	}

	private void addNodeListener(final JTree tree) {
		tree.getSelectionModel().addTreeSelectionListener(
				new TreeSelectionListener() {
					@Override
					public void valueChanged(TreeSelectionEvent e) {
						DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
								.getLastSelectedPathComponent();

						Object obj = ((DefaultMutableTreeNode) selectedNode).getUserObject();

						if (null != obj && obj instanceof ItemTree) {
							ItemTree itemTree = (ItemTree) selectedNode.getUserObject();
							if (null != itemTree) {
								AppController.getInstance().executeSketch(
										itemTree.visualItemName, itemTree.sketchFullName);
							}
						}
					}
				});
	}

	public void addTreeItem(EVisualType itemType, String visualItemName, String sketchClassName) {
		ItemTree item = new ItemTree(visualItemName, sketchClassName);
		DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(item);

		switch (itemType) {
		case BASIC_DATA_STRUCTURE:
			nodeBasicDS.add(childNode);
			break;
		case ADV_DATA_STRUCTURE:
			nodeAdvanceDS.add(childNode);
			break;
		case GRAPH_DATA_STRUCTURE:
			nodeGraphDS.add(childNode);
			break;
		case SORTING_ALGO:
			nodeSortingAlgo.add(childNode);
			break;
		case GRAPH_ALGO:
			nodeGraphAlgo.add(childNode);
			break;
		case MISC:
			nodeMisc.add(childNode);
			break;
		default:
			break;
		}
	}

	private class ItemTreeCellRenderer extends DefaultTreeCellRenderer {
		private static final long serialVersionUID = 7181519659862487404L;

		@Override
		public Component getTreeCellRendererComponent(JTree tree, Object value,
				boolean selected, boolean expanded, boolean leaf, int row,
				boolean hasFocus) {

			this.selected = selected;
			this.hasFocus = hasFocus;

			if (selected) {
				setBackgroundSelectionColor(Color.black);
				setTextSelectionColor(Color.white);
				super.setBackground(getBackgroundSelectionColor());
				setForeground(getTextSelectionColor());
			} else {
				super.setBackground(getBackgroundNonSelectionColor());
				setForeground(getTextNonSelectionColor());
			}

			Object obj = ((DefaultMutableTreeNode) value).getUserObject();

			// FIXME minhvv: ImageIcon is loaded many times!!!
			if (obj instanceof ItemTree) {
				ItemTree item = (ItemTree) obj;
				this.setIcon(Utils.createImageIcon(item.getIconPath()));
				this.setText(item.visualItemName);
				// this.setToolTipText(item.getSketchClassName());
			} else {
				this.setIcon(null);
				this.setText(value.toString());
			}

			return this;
		}
	}

	private class ItemTree {
		public String visualItemName;
		public String sketchFullName;

		public ItemTree(String visualItemName, String sketchFullName) {
			this.visualItemName = visualItemName;
			this.sketchFullName = sketchFullName;
		}

		public String getIconPath() {
			return "/" + visualItemName + ".png";
		}
	}
}
